package com.atguigu.tingshu.order.interceptor.impl;

import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.order.interceptor.OrderHandlerInterceptor;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Arrays;

/**
 * 表单重复校验任务类 第二个执行
 * @author Petrichor
 */
@Service
@Slf4j
public class OrderRepeatSbumitValidOrderHandlerInterceptor implements OrderHandlerInterceptor {

    @Autowired
    private RedisTemplate<String , String> redisTemplate ;

    /**
     * @description: 表单重复校验任务
     * @author Petrichor
     * @date 2024/1/7 23:22
     * @param orderInfoVo 订单信息
     * @return orderInfoVo 订单信息
     **/
    @Override
    public OrderInfoVo sbumitOrderRequestProcess(OrderInfoVo orderInfoVo) {
        // 获取订单id
        String tradeNo = orderInfoVo.getTradeNo();
        // 如果没有订单id 直接报错
        if(StringUtils.isEmpty(tradeNo)) {
            throw new GuiguException(ResultCodeEnum.DATA_ERROR) ;
        }
        // 原子性 为了获取redis中的 订单no
        // 定义lua脚本
        String script = "if redis.call('exists' , KEYS[1])\n" +
                "then\n" +
                "    return redis.call('del' , KEYS[1])\n" +
                "else\n" +
                "    return 0\n" +
                "end" ;

        // 执行lua脚本
        Long result = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Arrays.asList(RedisConstant.ORDER_TRADE_NO + tradeNo));
        // 说明 redis中没有相关数据 直接抛出异常
        if(result == 0) {
            throw new GuiguException(ResultCodeEnum.REPEAT_SUBMIT) ;
        }

        return orderInfoVo;
    }

    @Override
    public int sort() {
        return 2;
    }
}